
if (typeof Alkaline == 'undefined')
	var Alkaline = { Modules: {}, Processing: {} };

Alkaline.MODULE_TYPES = {
	OUTPUT: {}
};

Alkaline.init = function() {
	Alkaline.JSInfo.init();
	Alkaline.TreeBuilder.init();
	Alkaline.Processing.PropertyDescriptor.init();
	Alkaline.init = null;
}

Alkaline.run = function(args, stdOut, stdErr, stdWarn) {
	if (!stdOut)
		stdOut =
			typeof echo == 'function' ? echo :
			typeof print == 'function' ? print :
			(typeof console != 'undefined' && console.info) ? console.info :
			typeof WScript != 'undefined' ? WScript.Echo :
			alert;
	if (!stdErr)
		stdErr =
			(typeof console != 'undefined' && console.error) ? console.error :
			function(msg) {
				stdOut("[Err] " + msg);
			};
	if (!stdWarn)
		stdWarn =
			(typeof console != 'undefined' && console.warn) ? console.warn :
			function(msg) {
				stdOut("[Warn] " + msg);
			};
	
	var compileResult = new Alkaline.CompileResult(stdOut, stdErr, stdWarn);
	
	nextArgument:
	for (var i = 0; i < args.length; i++)
		if (args[i].charAt(0) == '-') {
			var arg = args[i].substr(1);
			switch (arg) {
				case 'm':
				case '-module':
					i++;
					var moduleName = args[i];
					compileResult.addModule(moduleName);
					break;
				default:
					if (Alkaline.Modules[arg.toLowerCase()]) {
						// if it is the name of a module, add it
						compileResult.addModule(arg);
						continue nextArgument;
					}
					if (arg.charAt(0) == '-') arg = arg.substr(1);
					if (compileResult.supportsArgument(arg)) {
						var extraC = compileResult.getArgumentArity(arg);
						var options = [];
						while (extraC--) options.push(args[++i]);
						compileResult.setArgument(arg, options);
						continue nextArgument;
					}
					stdWarn('Ignoring unknown option: ' + args[i]);
			}
		} else
			compileResult.inputSource.addFile(args[i]);

	compileResult.run();
	return compileResult;
}

Alkaline.parse = function(code) {
	var compileResult = new Alkaline.CompileResult(console.log, console.error, console.warn);
	compileResult.inputSource.addCode(code);
	compileResult.run();
	return compileResult;
}
